<template>
  <div class="app-container">
    <div class="main-layout">
      <!-- 左侧文件树 -->
      <div class="sidebar" v-if="items.length > 0">
        <div class="sidebar-header">
          <button class="btn-download" @click="exportCode">
            <img src="/icon/zip.svg" style="width: 14px; margin: 2px 4px 0 0" />
            下载压缩包
          </button>

          <a-tooltip placement="right">
            <template #title>关闭</template>
            <img src="/icon/close.svg" style="width: 18px; cursor: pointer" @click="onCancel" />
          </a-tooltip>
        </div>
        <d-tree
          style="height: calc(100vh - 66px); overflow-y: auto"
          :items="items"
          @file-selected="onFileSelected"
        />
      </div>

      <!-- 右侧内容显示区 -->
      <div class="content-area">
        <div v-if="selectedFile" class="file-content">
          <!-- 美化后的内容标题栏 -->
          <div class="content-header">
            <h3 class="file-name">{{ selectedFile.name }}</h3>
            <button class="btn-copy" @click="copyContent(selectedFile.content)">
              <img src="/icon/copy.svg" style="width: 18px" />
              复制
            </button>
          </div>
          <div
            class="content-text"
            v-if="selectedFile.content"
            v-html="renderMsg(selectedFile)"
          ></div>
        </div>
        <div v-else class="placeholder">
          <p>请选择一个文件以查看内容</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import DTree from '@/views/component/d-tree.vue'
import { message } from 'ant-design-vue'
import copy from 'copy-to-clipboard'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark-reasonable.css'
import JSZip from 'jszip'
import markdownIt from 'markdown-it'
import { onMounted, ref } from 'vue'

// 定义 props
const props = defineProps({
  files: {
    type: Array,
    required: true
  }
})

const emit = defineEmits(['close'])

const md = new markdownIt({
  breaks: true,
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return `<div class="code-container"><pre class='hljs' style='padding:6px 12px; position: relative; border-radius: 4px;'><span class="code-item" style="display: none">${str}</span><code class='code'>${hljs.highlight(lang, str, true).value}</code></pre></div>`
      } catch (__) {}
    }
    return `<div class="code-container"><pre class='hljs' style='padding:6px 12px; position: relative; border-radius: 4px;'><span class="code-item" style="display: none">${str}</span><code>${md.utils.escapeHtml(str)}</code></pre></div>`
  }
})

const renderMsg = (file) => {
  return md.render('```' + file.extension + ' \n' + file.content + '\n```')
}

// 当前选中的文件
const selectedFile = ref(null)
const items = ref([])

// 处理文件选中事件
const onFileSelected = (file) => {
  selectedFile.value = file
}

const buildFileTree = (files) => {
  const rootMap = new Map() // 用于构建森林（多个根）
  files.forEach((file) => {
    const pathParts = file.fileName.split('/')
    const filename = pathParts.pop()
    const [baseName, ext] = filename.split('.')
    let current = rootMap
    // 逐级构建路径
    for (const part of pathParts) {
      if (!current.has(part)) {
        current.set(part, {
          childrenMap: new Map(),
          node: {
            id: part,
            name: part,
            type: 'folder',
            expanded: true,
            children: []
          }
        })
      }
      current = current.get(part).childrenMap
    }
    // 添加文件叶子节点
    const fileNode = {
      id: filename,
      name: filename,
      type: 'file',
      extension: ext,
      content: file.content,
      fullPath: file.fileName
    }
    current.set(filename, {
      node: fileNode
    })
  })

  // 递归将 Map 结构转换为 children 数组
  const convertToTree = (map) => {
    const result = []
    for (const item of map.values()) {
      const node = item.node
      if (node.type === 'folder') {
        const childrenMap = item.childrenMap
        if (childrenMap && childrenMap.size > 0) {
          node.children = convertToTree(childrenMap)
        }
      }
      result.push(node)
    }
    return result
  }
  return convertToTree(rootMap)
}

function copyContent(content) {
  copy(content)
  message.success('已复制')
}

function onCancel() {
  emit('close')
}

function exportCode() {
  const zip = new JSZip()
  props.files.forEach((file) => {
    zip.file(file.fileName, file.content)
  })
  zip.generateAsync({ type: 'blob' }).then(function (blob) {
    const a = document.createElement('a')
    const url = window.URL.createObjectURL(blob)
    a.href = url
    a.download = 'export.zip'
    a.click()
    window.URL.revokeObjectURL(url)
  })
}

onMounted(() => {
  items.value = buildFileTree(props.files)
})
</script>

<style scoped>
.app-container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f8f9fa;
}

.main-layout {
  width: 100%;
  display: flex;
  overflow: hidden;
}

.sidebar {
  width: 300px;
  background-color: #ffffff;
  border-right: 1px solid #dee2e6;
  overflow-y: auto;
  padding: 6px 12px;
  box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}

/* 美化左侧顶部操作栏 */
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 12px;
  background-color: white;
}

.status-indicator {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: 16px;
  font-size: 14px;
  font-weight: 500;
}

.status-indicator.success {
  background-color: #e6f7e6;
  color: #138413;
  border: 1px solid #b2f2b2;
}

.status-indicator .icon {
  margin-right: 6px;
}

.btn-download {
  background-color: #1890ff;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition: background-color 0.2s;
  box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2);
}

.btn-download:hover {
  background-color: #40a9ff;
  box-shadow: 0 4px 8px rgba(24, 144, 255, 0.3);
}

.btn-download:active {
  transform: translateY(1px);
}

/* 右侧内容区 */
.content-area {
  width: calc(100vw - 580px);
  padding: 12px;
  overflow: auto;
  background-color: #ffffff;
}

.file-content {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* 美化内容标题栏 */
.content-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #e0e0e0;
}

.file-name {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #333;
  flex: 1;
}

.btn-copy {
  background-color: #f0f0f0;
  color: #555;
  border: 1px solid #ddd;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition: all 0.2s;
}

.btn-copy:hover {
  background-color: #e0dafe;
  color: #715beb;
}

.btn-copy:active {
  transform: translateY(1px);
}

/* 内容文本 */
.content-text {
  font-family: 'Courier New', monospace;
  overflow: auto;
  border-radius: 4px;
}

/* 占位符 */
.placeholder {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #999;
  font-size: 16px;
}

/* 图标样式 */
.icon {
  flex-shrink: 0;
}
</style>
